﻿// ==================================================================================================
// Copyright(C) 2018 FI Ltd. All rights reserved.
//
// SYSTEM NAME	    : FI.Net Application Framework
// COMPONENT ID	    : FI.Core
// COMPONENT DESC   : The foundation component of the whole framework. 	
//
// CREATED DATE/BY  : 30 Nov 2011 / Tian Mi
//
// REVISION HISTORY :	
// DATE/BY			SR#/CS/PM#/OTHERS		DESCRIPTION OF CHANGE
// ==================================================================================================
using System;
using Microsoft.Practices.ObjectBuilder2;
using Microsoft.Practices.Unity.InterceptionExtension;
using Microsoft.Practices.Unity.Utility;

namespace FI.Core.IoC
{
    /// <summary>
    /// Default <see cref="IInstanceInterceptor"/> provision policy.
    /// </summary>
    public abstract class AutoInterceptorPolicy
    {
        /// <summary>
        /// Gets the <see cref="IInstanceInterceptor"/>.
        /// </summary>
        public abstract IInstanceInterceptor Interceptor { get; }
    }

    /// <summary>
    /// A <see cref="AutoInterceptorPolicy"/> with an existing <see cref="IInstanceInterceptor"/>.
    /// </summary>
    public class FixedAutoInterceptorPolicy : AutoInterceptorPolicy
    {
        private IInstanceInterceptor interceptor;

        /// <summary>
        /// Initializes a new instance of the <see cref="FixedAutoInterceptorPolicy"/> class.
        /// </summary>
        /// <param name="interceptor">The interceptor.</param>
        public FixedAutoInterceptorPolicy(IInstanceInterceptor interceptor)
        {
            Guard.ArgumentNotNull(interceptor, "interceptor");
            this.interceptor = interceptor;
        }

        /// <summary>
        /// Gets the <see cref="IInstanceInterceptor"/>.
        /// </summary>
        public override IInstanceInterceptor Interceptor
        {
            get { return interceptor; }
        }
    }

    /// <summary>
    /// A <see cref="AutoInterceptorPolicy"/> which resolve the <see cref="IInstanceInterceptor"/> based on the given <see cref="NamedTypeBuildKey"/>.
    /// </summary>
    public class ResolvedAutoInterceptorPolicy : AutoInterceptorPolicy
    {
        // Fields
        /// <summary>
        /// Gets the build key.
        /// </summary>
        public NamedTypeBuildKey BuildKey { get; private set; }

        /// <summary>
        /// A delegate to resove the <see cref="IInstanceInterceptor"/> based on the given <see cref="NamedTypeBuildKey"/>.
        /// </summary>
        public Func<NamedTypeBuildKey, IInstanceInterceptor> InterceptorResolver;

        /// <summary>
        /// Initializes a new instance of the <see cref="ResolvedAutoInterceptorPolicy"/> class.
        /// </summary>
        /// <param name="interceptorResolver">The interceptor resolver.</param>
        /// <param name="buildKey">The build key.</param>
        public ResolvedAutoInterceptorPolicy(Func<NamedTypeBuildKey, IInstanceInterceptor> interceptorResolver,NamedTypeBuildKey buildKey)
        {
            Guard.ArgumentNotNull(interceptorResolver, "interceptorResolver");
            Guard.ArgumentNotNull(buildKey, "buildKey");

            this.BuildKey = buildKey;
            this.InterceptorResolver = interceptorResolver;
        }

        /// <summary>
        /// Gets the <see cref="IInstanceInterceptor"/>.
        /// </summary>
        public override IInstanceInterceptor Interceptor
        {
            get { return this.InterceptorResolver.Invoke(this.BuildKey); }
        }
    }
}
